
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# Data for Table_A6
data = {'Acts on citizen feedback': [0.118, -0.04, 0.002, -0.018, -0.047], 'Takes citizen report seriously': [0.059, -0.134, 0.085, -0.01, 0.014], 'Responds timely': [0.021, -0.193, 0.135, 0.001, -0.026], 'Not corrupt': [0.128, -0.048, -0.068, -0.123, 0.077], 'Provides equal service': [0.08, -0.204, 0.033, -0.008, 0.03], 'I trust the police': [0.085, -0.088, 0.079, -0.077, -0.018], 'Provides satisfactory service': [0.079, -0.196, 0.158, -0.017, -0.085]}

# Standard errors
std_errors = {'Acts on citizen feedback': [0.064, 0.071, 0.069, 0.051, 0.069], 'Takes citizen report seriously': [0.059, 0.068, 0.06, 0.055, 0.058], 'Responds timely': [0.096, 0.088, 0.124, 0.091, 0.084], 'Not corrupt': [0.104, 0.121, 0.131, 0.097, 0.092], 'Provides equal service': [0.088, 0.081, 0.084, 0.09, 0.07], 'I trust the police': [0.063, 0.061, 0.068, 0.06, 0.051], 'Provides satisfactory service': [0.07, 0.064, 0.075, 0.06, 0.058]}

# Independent variable labels
iv_labels = ['Extraversion', 'Agreeableness', 'Conscientiousness', 'Neuroticism (Reverse-coded)', 'Openness']

# Convert the data and standard errors to DataFrames
df = pd.DataFrame(data, index=iv_labels)
df_se = pd.DataFrame(std_errors, index=iv_labels)

# Function to calculate T-values from coefficients and standard errors
def calculate_t_values(df, df_se):
    return df / df_se

# Calculate T-values
t_values_df = calculate_t_values(df, df_se)

# Generate significance annotations based on T-values
annotations = t_values_df.applymap(lambda x: '***' if abs(x) > 2.576 else '**' if abs(x) > 1.96 else '*' if abs(x) > 1.645 else '')

# Plotting the heatmap
plt.figure(figsize=(12, 6))

# Plot the heatmap with significance annotations and black-and-white gradient
ax = sns.heatmap(t_values_df.astype(float), annot=annotations, fmt="", cmap="Greys", center=0,
                 linewidths=0.5, cbar_kws={'label': 'T-values', 'orientation': 'horizontal'}, mask=t_values_df.isnull())

# Adjust labels and angles
ax.xaxis.tick_top()
ax.xaxis.set_label_position('top')
ax.set_xticklabels(t_values_df.columns, rotation=45, ha="center", fontsize=10)
ax.set_yticklabels(t_values_df.index, rotation=0, fontsize=10)

# Position the color bar (legend) at the bottom
cbar = ax.collections[0].colorbar
cbar.ax.xaxis.set_label_position('bottom')
cbar.ax.xaxis.set_ticks_position('bottom')

# Adjust layout
plt.tight_layout()
plt.show()
